import math
import os
import re

import matplotlib.pyplot as plt
import pandas as pd

treePoints = []
treeRadius = []

lastMappID = 0


def getTreePoints(mapID, otherMap='无'):
    global treePoints
    global lastMappID
    if treePoints and lastMappID == mapID: return treePoints
    lastMappID = mapID
    if mapID == 1:
        excel_file = '..\\data\\4-拙政园数据坐标.xlsx'
    elif mapID == 2:
        excel_file = '..\\data\\4-留园数据坐标.xlsx'
    elif mapID == 3:
        excel_file = '..\\data\\4-寄畅园数据坐标.xlsx'
    elif mapID == 4:
        excel_file = '..\\data\\4-瞻园数据坐标.xlsx'
    elif mapID == 5:
        excel_file = '..\\data\\4-豫园数据坐标.xlsx'
    elif mapID == 6:
        excel_file = '..\\data\\4-秋霞圃数据坐标.xlsx'
    elif mapID == 7:
        excel_file = '..\\data\\4-沈园数据坐标.xlsx'
    elif mapID == 8:
        excel_file = '..\\data\\4-怡园数据坐标.xlsx'
    elif mapID == 9:
        excel_file = '..\\data\\4-耦园数据坐标.xlsx'
    elif mapID == 10:
        excel_file = '..\\data\\4-绮园数据坐标.xlsx'
    else:
        excel_file = os.path.join('..\\data\\', otherMap)
    # 读取Excel的“道路”工作表
    df = pd.read_excel(excel_file, sheet_name='植物')
    # 提取第一列数据（区分线段的坐标）
    if mapID == 10:
        raw_data = df.iloc[:, 1].dropna().astype(str)
    elif mapID > 10:
        raw_data = df.iloc[:, 0].dropna().astype(str)
    else:
        raw_data = df.iloc[:, 0].dropna().astype(str)
    segments = []  # 存储所有线段
    current_segment = []  # 当前线段点列表
    for item in raw_data:
        if item.startswith('            {0;'):
            # 新线段开始：保存当前线段（如果有），并重置
            if current_segment:
                segments.append(current_segment)
            current_segment = []
            segment_id = int(re.findall(r'\d+', item)[0])  # 提取线段ID
        else:
            # 解析坐标点：格式为 "{x,y,z}"
            if mapID > 10:
                match = re.match(r'\(([-\d.]+), ([-\d.]+), ([-\d.]+)\)', item)
            else:
                match = re.match(r'\{([-\d.]+), ([-\d.]+), ([-\d.]+)\}', item)
            if match:
                x = float(match.group(1))
                y = float(match.group(2))
                current_segment.append((x, y))

    if current_segment:
        segments.append(current_segment)
    treePoints = segments
    return segments


def getTreeRadius(mapID, otherMap='无'):
    global treeRadius
    global lastMappID
    if treeRadius and lastMappID == mapID: return treeRadius
    lastMappID = mapID
    if mapID == 1:
        excel_file = '..\\data\\4-拙政园数据坐标.xlsx'
    elif mapID == 2:
        excel_file = '..\\data\\4-留园数据坐标.xlsx'
    elif mapID == 3:
        excel_file = '..\\data\\4-寄畅园数据坐标.xlsx'
    elif mapID == 4:
        excel_file = '..\\data\\4-瞻园数据坐标.xlsx'
    elif mapID == 5:
        excel_file = '..\\data\\4-豫园数据坐标.xlsx'
    elif mapID == 6:
        excel_file = '..\\data\\4-秋霞圃数据坐标.xlsx'
    elif mapID == 7:
        excel_file = '..\\data\\4-沈园数据坐标.xlsx'
    elif mapID == 8:
        excel_file = '..\\data\\4-怡园数据坐标.xlsx'
    elif mapID == 9:
        excel_file = '..\\data\\4-耦园数据坐标.xlsx'
    elif mapID == 10:
        excel_file = '..\\data\\4-绮园数据坐标.xlsx'
    else:
        excel_file = os.path.join('..\\data\\', otherMap)
    # 读取Excel的“道路”工作表
    df = pd.read_excel(excel_file, sheet_name='植物')

    # 提取第一列数据（区分线段的坐标）
    if mapID == 10:
        raw_data = df.iloc[:, 2].dropna().astype(str)
    elif mapID > 10:
        raw_data = df.iloc[:, 0].dropna().astype(str)
    else:
        raw_data = df.iloc[:, 1].dropna().astype(str)
    segments = []  # 存储所有线段
    current_segment = []  # 当前线段点列表

    for item in raw_data:
        if mapID > 10:
            r = 1800
            current_segment.append(r)
        else:
            # 解析坐标点
            match = re.match(r'(\d+)', item)
            if match:
                r = int(match.group(0))
                current_segment.append(r)
    if current_segment:
        segments.append(current_segment)
    treeRadius = segments
    return segments


def getTreeAreaAndCount(mapID):
    radius = getTreeRadius(mapID)[0]
    area = 0
    for r in radius:
        area = area + math.pi * r * r
    return area, len(radius)


def getTreeD_ob(mapID, tree_kdtree):
    points = getTreePoints(mapID)[0]
    d = 0
    for point in points:
        dist, idx = tree_kdtree.query(point, k=2)
        d = d + dist[1]
    return d / len(points)
